var MILLISECONDS = 1000;
var SECONDS = 60;
var MINUTES = 60;
var HOURS = 24;

String.prototype.contains = function(it) { return this.indexOf(it) != -1; };

function getRandomNumber(maxBoundary){
	return Math.floor(Math.random()*maxBoundary);
}

/*
##############  Storage #####################
*/

var SYNCHRONIZE_INTERVAL = 300000;

function storageSet(element, value){
	if(!element.contains('-frequency') && !element.contains('-displayed') && !element.contains('-date')){
		localStorage.hasChanged = "1";
	}
	localStorage[element] = value;
}

function storageGet(element){
	return localStorage[element];
}

function storageRemove(element){
	return localStorage.removeItem(element);
}

function hasRemoteAccount(){
	return storageGet('token') && storageGet('token') != "" ;
}

function getNameValue(name){
	return {name: name, value: storageGet(name)};
}


function removeDynamicElement(list, element) {
	var elementList = storageGet(list).split('|').filter(function(value){
		return value != element;
	});
	storageSet(list, "");
	$.each(elementList, function (intIndex, element){
		if(storageGet(list) != ""){
			storageSet(list,  storageGet(list) + '|' + element);	
		} else {
			storageSet(list,  storageGet(list) + element);
		}
	});
	$.each(DYNAMIC_STORAGE, function (intIndex, storageElement){
		if(storageElement.name == list){
			$.each(storageElement.types, function (intIndex, type){
				storageRemove(element  + '-' + type);
			});
		}
	});
}


function ajaxPost(url, data, callback){
	if(typeof(ENV) != "undefined" && ENV == "test"){
		simulatePost(url, data, callback);
	} else {
		$.post(url, data, callback);
	}
}

//remote service
function login(login, password, callback){
	ajaxPost(REMOTE_URL + 'extension-login.php', {extensionId: EXTENSION_ID, login: login, password: password}, function(resultString){
		var result = jQuery.parseJSON(resultString);
		if(result.token){
			storageSet('token', result.token);
			storageSet('login', login);
		}
		if(result.error){
			alert("Error: " + result.error);
		} else {
			if(callback){
				callback();
			}
		}
	});
}

//remote service
function saveConfiguration(callback){
	localStorage.timestamp = new Date().getTime();
	var data = new Array();
	$.each(
		STATIC_STORAGE,
		function(intIndex, element){
			data.push(getNameValue(element));
		}
	);
	
	$.each(
		DYNAMIC_STORAGE,
		function(intIndex, storageList){
			$.each(storageGet(storageList.name).split(STORAGE_SEPARATOR),
				function(intIndex, element){
					$.each(storageList.types,
						function(intIndex, type){
							data.push(getNameValue(element + '-' + type));
						}
					);
				});
		});
	ajaxPost(REMOTE_URL + 'extension-set.php', {extensionId: EXTENSION_ID, token: storageGet('token'), data: data}, function(resultString){
		var result = jQuery.parseJSON(resultString);
		if(result.error){
			alert("Error: " + result.error);
		} else {
			localStorage.hasChanged = "0";
			if(callback){
				callback();
			}
		}
	});
}

//remote service
function retrieveConfiguration(callback){
	ajaxPost(REMOTE_URL + 'extension-get.php', {extensionId: EXTENSION_ID, token: storageGet('token')}, function(resultString){
		var result = jQuery.parseJSON(resultString);
		
		if(result.error){
			alert("Error: " + result.error);
		} else {
			$.each(
				result.data,
				function(intIndex, element){
					if(element.name.contains("List")){
						var newList = element.value.split(STORAGE_SEPARATOR);
						var oldList = localStorage[element.name].split(STORAGE_SEPARATOR);
						$.each(newList, function (newIndex, newElement){
							var added = true;
							$.each(oldList, function (oldIndex, oldElement){
								if(oldElement == newElement){
									added = false;
								}
							});
							if(added && newElement != ""){
								if(storageGet(element.name) != ""){
									storageSet(element.name,  storageGet(element.name) + '|' + newElement);	
								} else {
									storageSet(element.name,  storageGet(element.name) + newElement);
								}
							}
						});
					} else {
						localStorage[element.name] = element.value;
					}
				}
			);
			if(callback){
				callback();
			}
		}
		
	});
}

//remote service
function getTimestamp(callback){
	ajaxPost(REMOTE_URL + 'extension-get-timestamp.php', {extensionId: EXTENSION_ID, token: storageGet('token')}, function(resultString){
		var result = jQuery.parseJSON(resultString);
		if(result.error){
			alert("Error: " + result.error);
		} else {
			if(result.timestamp && result.timestamp != ""){
				callback(result.timestamp);
			} else {
				callback();
			}
		}		
	});
}

//remote service
function sendMessage(message, callback){
	ajaxPost(REMOTE_URL + 'extension-message-set.php', {extensionId: EXTENSION_ID, message: message}, function(resultString){
		var result = jQuery.parseJSON(resultString);
		if(result.error){
			alert("Error: " + result.error);
		} else {
			if(callback){
				callback();
			}
		}		
	});
}


function synchronizeLoop(){
	window.setTimeout(synchronizeLoop, SYNCHRONIZE_INTERVAL);
	if(hasRemoteAccount()){
		synchronize();
	}
}

function synchronize(callback){
		var callbackTimestamp = function(timestamp){
			
			if(timestamp && (parseInt(timestamp) > parseInt(storageGet('timestamp')) || !storageGet('timestamp'))){
				var retrieveCallBack = function() {
					saveConfiguration(callback);
				};
				retrieveConfiguration(retrieveCallBack);
				localStorage.synchro = "0";
			} else {
				if(storageGet('hasChanged') == "1" || !timestamp){
					var saveCallBack = function() {
						retrieveConfiguration(callback);
					};
					saveConfiguration(saveCallBack);
				}
				localStorage.synchro = "1";
			}
		};		
		getTimestamp(callbackTimestamp);	
}

function saveElement(name, value) {
	storageSet(name, value);
}

//insert storage UI in page
function insertCommonUI(){
	$('#header').append($('<div></div>')
		.addClass('messageLabel')
		.attr("id","messageBlock")
		.text("I don't like this app")
		.click(function(){
			if($('#messageBlock').text().contains("I")){
				$('#messageBlock').empty();
				$('#messageBlock')
					.append($('<textarea></textarea>')
						.addClass('messageText')
						.attr("id","messageText")
						.val("Tell me why !!"))
					.append($('<br/>'))
					.append($('<span></span>')
						.addClass('littlebutton')
						.addClass('messageButton')
						.text("Send")
						.click(function(){
							var callbackSent = function(){
								$('#messageBlock').empty();
								$('#messageBlock').append("Message sent !");
							};
							sendMessage($('#messageText').val(), callbackSent);
						}));
			}
		}));
	if(hasRemoteAccount()){
		$('#header').append($('<span></span>')
			.addClass('log')
			.text('logged as ' + storageGet('login'))
		);
		$('#footer').append($('<span></span>')
			.text('disable remote behavior')
			.addClass('account')
			.click(function(){
				$('#logBlock').empty();
				storageRemove('login');
				storageRemove('token');
				storageRemove('timestamp');								
				init();
			}));
	} else {
		$('#footer').append($('<div></div>')
			.text("set up a remote account")
			.addClass('account')
			.click(function(){
				if(!$('#footer').text().contains("Login")){
					$('#footer')
						.append($('<span></span>')
							.text('Login :'))
						.append($('<input type="text"/>')
							.attr("id", "login"))
						.append($('<span></span>')
							.text('Password :'))
						.append($('<input type="password" />')
							.attr("id", "password"))						
						.append($('<span></span>')
							.addClass('littlebutton')
							.text("OK")
							.click(function(){
								var userLogin = $('#login').val();
								var userPassword = $('#password').val();
								if(userLogin != "" && userLogin.length > SECURITY_LENGTH && userPassword != "" && userPassword.length > SECURITY_LENGTH){
									var callback = function(){
										synchronize(init);
									};
									login(userLogin, userPassword, callback);
								} else {
									alert("The login/password is not defined or is too short");
								}
							}));
				}
			}));
	}
}


/*
 *	###########  Generic widget ################
 */
function getValueInput(id){
	if(storageGet(id)){
		return storageGet(id);
	} else { 
		return "";
	}	
}

function getOptionTextArea(id, className){	
	return $('<textarea></textarea>')
			.addClass(className)
			.addClass('savedElement')
			.attr('id', id)
			.keyup(function(){
				saveElement(id, this.value);
			})
			.val(getValueInput(id));
}

function getOptionInputText(id, className){
	return $('<input type="text" value="' + getValueInput(id) +  '" />')
			.addClass('savedElement')
			.addClass(className)
			.keyup(function(){
				saveElement(id, this.value);
			})
			.attr('id', id);
}

function getOptionSelect(id, className){
	return $('<select></select>')
		.addClass(className)
		.addClass('savedElement')
		.attr('id', id)
		.change(function(){
			saveElement(id, this.value);
		});
}

function getNameWithUppercase(name){
	return name.substr(0, 1).toUpperCase() + name.substr(1);
}

function getMessageFromTime(time){
	var value;
	var timeInterval;
	if(time > MILLISECONDS * SECONDS * MINUTES * HOURS){
		value = Math.round(time / (MILLISECONDS * SECONDS * MINUTES * HOURS));
		timeInterval = " day";
	} else if (time > MILLISECONDS * SECONDS * MINUTES){
		value = Math.round(time / (MILLISECONDS * SECONDS * MINUTES));
		timeInterval = " hour";
	} else if (time > MILLISECONDS * SECONDS){
		value = Math.round(time / (MILLISECONDS * SECONDS));
		timeInterval = " minute";
	} else if (time > MILLISECONDS){
		value = Math.round(time / MILLISECONDS);
		timeInterval = " second";
	}
	if (value > 1){
		timeInterval += "s";
	}
	return value + timeInterval;
}